//
//  ZSNBroadCastViewController.swift
//  AgoraBroadCastNewSwiftZhaosn
//
//  Created by zhaosuning on 2022/3/14.
//

import UIKit
import AgoraRtcKit

class ZSNBroadCastViewController: UIViewController {
    
    var agoraKit: AgoraRtcEngineKit!
    var role: AgoraClientRole = .broadcaster
    
    var localView: UIView!
    var remoteView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.view.backgroundColor = UIColor.white
        self.title = "直播"
        
        let btnJoinChannel = UIButton.init(frame: CGRect(x: 30, y: 100, width: 160, height: 50))
        btnJoinChannel.backgroundColor = UIColor.green
        btnJoinChannel.setTitle("点击进入频道", for: .normal)
        btnJoinChannel.layer.cornerRadius = 23.5
        btnJoinChannel.titleLabel?.textAlignment = .center
        btnJoinChannel.layer.masksToBounds = true
        btnJoinChannel.titleLabel?.font = UIFont.systemFont(ofSize: 20)
        btnJoinChannel.setTitleColor(UIColor(red: 50/255, green: 71/255, blue: 1, alpha: 1), for: UIControl.State.normal)
        btnJoinChannel.addTarget(self, action: #selector(btnJoinChannelClick), for: UIControl.Event.touchUpInside)
        self.view.addSubview(btnJoinChannel)
        
        let btnLeaveChannel = UIButton.init(frame: CGRect(x: 30, y: 160, width: 160, height: 50))
        btnLeaveChannel.backgroundColor = UIColor.green
        btnLeaveChannel.setTitle("离开频道", for: .normal)
        btnLeaveChannel.layer.cornerRadius = 23.5
        btnLeaveChannel.titleLabel?.textAlignment = .center
        btnLeaveChannel.layer.masksToBounds = true
        btnLeaveChannel.titleLabel?.font = UIFont.systemFont(ofSize: 20)
        btnLeaveChannel.setTitleColor(UIColor(red: 50/255, green: 71/255, blue: 1, alpha: 1), for: UIControl.State.normal)
        btnLeaveChannel.addTarget(self, action: #selector(btnLeaveChannelClick), for: UIControl.Event.touchUpInside)
        self.view.addSubview(btnLeaveChannel)
        
        let btnDestroy = UIButton.init(frame: CGRect(x: 30, y: 220, width: 160, height: 50))
        btnDestroy.backgroundColor = UIColor.green
        btnDestroy.setTitle("销毁", for: .normal)
        btnDestroy.layer.cornerRadius = 23.5
        btnDestroy.titleLabel?.textAlignment = .center
        btnDestroy.layer.masksToBounds = true
        btnDestroy.titleLabel?.font = UIFont.systemFont(ofSize: 20)
        btnDestroy.setTitleColor(UIColor(red: 50/255, green: 71/255, blue: 1, alpha: 1), for: UIControl.State.normal)
        btnDestroy.addTarget(self, action: #selector(btnDestroyClick), for: UIControl.Event.touchUpInside)
        self.view.addSubview(btnDestroy)
        
        localView = UIView.init()
        localView.backgroundColor = UIColor.yellow
        localView.frame = CGRect(x: 10, y: 280, width: 150, height: 150)
        self.view.addSubview(localView)
        
        remoteView = UIView.init()
        remoteView.frame = CGRect(x: 10, y: 440, width: 200, height: 200)
        remoteView.backgroundColor = UIColor.blue
        self.view.addSubview(remoteView)
        
    }
    
    
    @objc func btnDestroyClick() {
        AgoraRtcEngineKit.destroy()
    }
    
    @objc func btnJoinChannelClick() {
        joinChannella()
    }
    
    @objc func btnLeaveChannelClick() {
        if (agoraKit != nil) {
            agoraKit.leaveChannel { (stats) -> Void in
                NSLog("打印了 离开频道")
            }
        }
    }
    
    func joinChannella() {
        let config = AgoraRtcEngineConfig()
        config.appId = ZSNComDef.AppId
        config.channelProfile = .liveBroadcasting
        agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self)
        let channelName = ZSNComDef.ChannelName
        
        //let options = AgoraClientRoleOptions()
        //options.audienceLatencyLevel = .ultraLowLatency
        //options.audienceLatencyLevel = .lowLatency
        //agoraKit.setClientRole(.audience, options: options)
        
        agoraKit.setClientRole(.broadcaster, options: nil)
        
        //agoraKit.setParameters("{\"rtc.audio.force_bluetooth_a2dp\": true}")
        
        //agoraKit.setParameters("{\"rtc.audio.force_bluetooth_a2dp\": false}")
        
        agoraKit.setAudioProfile(.musicHighQuality, scenario: .gameStreaming)
        
        agoraKit.setVideoFrameDelegate(self)
        agoraKit.enableVideo()
        
        agoraKit.setVideoEncoderConfiguration(AgoraVideoEncoderConfiguration(size: AgoraVideoDimension640x360,
                                                                             frameRate: .fps30,
                                                                             bitrate: AgoraVideoBitrateStandard,
                                                                             orientationMode: .adaptative, mirrorMode: .auto))
        
        
        // setup raw media data observers
        agoraKit.setAudioFrameDelegate(self)
        
        agoraKit.setRecordingAudioFrameParametersWithSampleRate(44100, channel: 2, mode: .readOnly, samplesPerCall: 1024)
        agoraKit.setMixedAudioFrameParametersWithSampleRate(44100, channel: 1, samplesPerCall: 1024)
        agoraKit.setPlaybackAudioFrameParametersWithSampleRate(44100, channel: 1, mode: .readWrite, samplesPerCall: 1024)
        
        //耳返
        //开启耳返 不带AgoraEarMonitoringFilterType
        //agoraKit.enable(inEarMonitoring: true)
        
        
        //1: Do not add an audio filter to the in-ear monitor.
        //AgoraEarMonitoringFilterNone = (1<<0),
      
        //2: Add an audio filter to the in-ear monitor.
        //AgoraEarMonitoringFilterBuiltInAudioFilters = (1<<1),
            
        // Enable noise suppression to the in-ear monitor.
        //AgoraEarMonitoringFilterNoiseSuppression = (1<<2)
        
        //开启耳返 带AgoraEarMonitoringFilterType
        //不在耳返中添加 audio filter
        //agoraKit.enable(inEarMonitoring: true, includeAudioFilters: .none)
        
        //在耳返中添加人声效果 audio filter。如果你实现了美声、音效等功能，用户可以在耳返中听到添加效果后的声音
        agoraKit.enable(inEarMonitoring: true, includeAudioFilters: .builtInAudioFilters)
        
        //在耳返中添加降噪 audio filter
        //agoraKit.enable(inEarMonitoring: true, includeAudioFilters: .noiseSuppression)
        
        //调节音频采集信号音量,取值范围为 [0,400]
        agoraKit?.adjustRecordingSignalVolume(100)
        
        //设置耳返音量
        agoraKit.setInEarMonitoringVolume(80)
        
        agoraKit.setDefaultAudioRouteToSpeakerphone(true)
        let option = AgoraRtcChannelMediaOptions()
        option.publishCameraTrack = .of(true)
        option.clientRoleType = .of((Int32)(AgoraClientRole.broadcaster.rawValue))
        
        let result = agoraKit.joinChannel(byToken: ZSNComDef.Token, channelId: channelName, uid: 0, mediaOptions: option)
        if result != 0 {
            NSLog("打印了 进入频道失败 \(result)")
        }
        else {
            NSLog("打印了 进入频道返回0")
        }
    }
    
    func setupLocalVideo() {
        // 启用视频模块
        //agoraKit?.enableVideo()
        let videoCanvas = AgoraRtcVideoCanvas()
        videoCanvas.uid = 0
        videoCanvas.renderMode = .hidden
        videoCanvas.view = localView
        // 设置本地视图
        agoraKit?.setupLocalVideo(videoCanvas)
        agoraKit.startPreview()
    }
    
    func setupRemoteVideo(_ uid: UInt) {
        let videoCanvas = AgoraRtcVideoCanvas()
        videoCanvas.uid = uid
        videoCanvas.renderMode = .hidden
        videoCanvas.view = remoteView
        // 设置远端视图
        agoraKit?.setupRemoteVideo(videoCanvas)
    }
    

}


extension ZSNBroadCastViewController: AgoraRtcEngineDelegate {
    
    func rtcEngine(_ engine: AgoraRtcEngineKit, didOccurWarning warningCode: AgoraWarningCode) {
        NSLog("打印了 didOccurWarning: \(warningCode.rawValue)")
    }
    
    func rtcEngine(_ engine: AgoraRtcEngineKit, didOccurError errorCode: AgoraErrorCode) {
        NSLog("打印了 didOccurError: \(errorCode) Error \(errorCode.rawValue)")
        //self.showAlert(title: "Error", message: "Error \(errorCode.description) occur")
    }
    
    func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) {
        NSLog("打印了 didJoinChannel \(channel) with uid \(uid) elapsed \(elapsed)ms")
        
        setupLocalVideo()
    }
    
    func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) {
        NSLog("打印了 remote user join: \(uid) \(elapsed)ms")
        
        setupRemoteVideo(uid)
    }
    
    func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) {
        NSLog("打印了 remote user left: \(uid) reason \(reason)")
    }
}

extension ZSNBroadCastViewController: AgoraAudioFrameDelegate {
    func onEarMonitoringAudioFrame(_ frame: AgoraAudioFrame) -> Bool {
        NSLog("打印了 onEarMonitoringAudioFrame 无频道")
        return false
    }
    
    
    func onRecord(_ frame: AgoraAudioFrame, channelId: String) -> Bool {
        NSLog("打印了 onRecord")
        return false
    }
    
    func onPlaybackAudioFrame(_ frame: AgoraAudioFrame, channelId: String) -> Bool {
        NSLog("打印了 onPlaybackAudioFrame 1")
        return false
    }
    
    func onMixedAudioFrame(_ frame: AgoraAudioFrame, channelId: String) -> Bool {
        NSLog("打印了 onMixedAudioFrame")
        return false
    }
    
    func onPlaybackAudioFrame(beforeMixing frame: AgoraAudioFrame, channelId: String, uid: UInt) -> Bool {
        NSLog("打印了 onPlaybackAudioFrame beforeMixing")
        return false
    }
    
    func onEarMonitoringAudioFrame(_ frame: AgoraAudioFrame, channelId: String) -> Bool {
        NSLog("打印了 onEarMonitoringAudioFrame")
        return false
    }

    
}

extension ZSNBroadCastViewController: AgoraVideoFrameDelegate {
    
    func onCapture(_ videoFrame: AgoraOutputVideoFrame) -> Bool {
        NSLog("打印了 onCapture")
        return false
    }
    
    func onRenderVideoFrame(_ videoFrame: AgoraOutputVideoFrame, uid: UInt, channelId: String) -> Bool {
        NSLog("打印了 onRenderVideoFrame")
        return false
    }
    
    func getVideoFrameProcessMode() -> AgoraVideoFrameProcessMode {
        NSLog("打印了 getVideoFrameProcessMode return .readOnly")
        return .readOnly
    }
    
    func getVideoPixelFormatPreference() -> AgoraVideoFormat {
        NSLog("打印了 getVideoPixelFormatPreference return .cvPixel")
        return .cvPixel
    }
    
    func getMirrorApplied() -> Bool {
        NSLog("打印了 getMirrorApplied")
        return true
    }
    
    func getObservedFramePosition() -> UInt32 {
        
        NSLog("打印了 getObservedFramePosition")
        
        return 0
    }
    
    
}
